home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / lib / mntlib44.zoo / mntlib / crtinit.c < prev    next >
C/C++ Source or Header  |  1993-10-27  |  13KB  |  494 lines

  1. /*
  2.  *
  3.  * Crtinit: C run-time initialization code.
  4.  * Written by Eric R. Smith, and placed in the public domain.
  5.  * Use at your own risk.
  6.  *
  7.  * 01/03/89 ++jrb
  8.  *    The (new) meaning of _stksize: (thanks to allan pratt for the feedback)
  9.  *
  10.  *    _stksize            meaning
  11.  *      -1L        keep all of memory (except MINFREE at top) and do
  12.  *            mallocs from own heap, with heap grown upwards towards
  13.  *            stack, and the stack growing down towards heap,
  14.  *            with a minimum slush between them so that they
  15.  *            dont meet (only checked while malloc'ing). With
  16.  *            this model, further spawning is not possible, but it is
  17.  *            well suited for programs such as gcc-cc1 etc.
  18.  *            Thanks to Piet van Oostrum & Atze Dijkstra for this idea
  19.  *
  20.  *    0L        keep minimum amount of memory. this is also the
  21.  *            case when _stksize is undefined by the user.
  22.  *    1L        keep 1/4 of memory, free 3/4 ( as in Alcyon GEMSTART)
  23.  *    2L        keep 2/4 (1/2), free rest
  24.  *    3L        keep 3/4, free 1/4
  25.  *    other        keep that many bytes
  26.  *    -other        keep |other| bytes, use the heap for mallocs
  27.  *
  28.  * 02/14/90 ++jrb (thanks edgar)
  29.  *    auto acc detect
  30.  *    undump friendly
  31.  *
  32.  * NOTE: dumping applications should use _initial_stack instead: if
  33.  *     !=0, then _stksize is initialized from _initial_stack, and
  34.  *     mallocs are always from internal heap. (TeX works much better now),
  35.  *     thanks edgar!
  36.  *
  37.  * Acc convention:
  38.  *      Preferred: user sets _stksize, then _heapbase is set to Malloc(_stksize)
  39.  *      sp to _heapbase + _stksize and all mallocs happen from heap
  40.  *
  41.  *      Old way:
  42.  *    user sets _heapbase to bottom of stack + heap area
  43.  *         sets _stksize to the size of this area
  44.  *         at startup, sp will be set to top of this area
  45.  *         (_heapbase  + _stksize ) and malloc()'s will happen from heap.
  46.  *        (note malloc() and *not* Malloc())
  47.  *
  48.  * 02/16/90 ++jrb
  49.  *  - bug fix: dont get screwed by desktop launch when fast bit is set
  50.  *             convert env string to format usable
  51.  *        (atari get your act together!!)
  52.  *
  53.  * 09-20-92 hyc
  54.  *    Support base relative addressing, for shared-text execution.
  55.  *    Also merged in some stuff from ++jrb's crt0.c.
  56.  *
  57.  * Turbo / Pure C version 21-6-92 um
  58.  *   the Turbo / Pure linker reserves stack space in the BSS and sets
  59.  *   the symbol _StkSize to its size. If _StkSize is set to 0, we use
  60.  *   _stksize etc. as usual
  61.  *
  62.  * 19 Jan 93 hohmuth
  63.  *    new variable _PgmSize, holds size of program area
  64.  *    (useful when doing Ptermres)
  65.  *
  66.  * 08 Apr 93 hohmuth
  67.  *    added support for ARGV standard extension allowing empty arguments
  68.  *
  69.  */
  70.  
  71. /* define this symbol to get ARGV argument passing that's strictly
  72.  * compatible with the Atari standard. If it's not defined, then
  73.  * the startup code won't validate the ARGV= variable by checking
  74.  * the command byte for 0x127. Note that there are still some
  75.  * applications (gulam is a notable example) that implement only
  76.  * part of the standard and don't set the command byte to 0x127.
  77.  */
  78.  
  79. #if 0
  80. #define STRICTLY_COMPATIBLE_WITH_STANDARD
  81. #endif
  82.  
  83. #include <basepage.h>
  84. #include <osbind.h>
  85. #include <support.h>
  86. #include "lib.h"
  87.  
  88. #define isspace(c) ((c) == ' '||(c) == '\t')
  89. #define isdigit(c) ((c) >= '0' && (c) <= '9')
  90.  
  91. #define MINFREE    (8L * 1024L)        /* free at least this much mem */
  92.                     /* on top */
  93. #define MINKEEP (8L * 1024L)        /* keep at least this much mem */
  94.  
  95. BASEPAGE *_base;
  96. char **environ;
  97. static long argc;
  98. static char **argv;
  99.  
  100. /* size to be allocated for the stack */
  101. extern long _stksize;        /* picked up from user or from stksiz.c */
  102.  
  103. /* set to heap base addr when _stksize < 0 || _initial_stack || When DA
  104.  * note that we allow the user to provide a _heapbase of their own, since
  105.  * that used to be necessary for acc's; but that is no longer needed
  106.  * (or encouraged) since the acc startup code now Mallocs a heap
  107.  * automatically
  108.  */
  109. extern void *_heapbase;        /* picked up from user or from heapbase.c */
  110.  
  111. /*
  112.  * initial stack is used primarily by dumping application,
  113.  * if it is, malloc is always from heap, and _stksize is init
  114.  * from initial_stack (to preserve the value in the undumped run)
  115.  */
  116. extern long _initial_stack;    /* picked up from user or from inistack.c */
  117.  
  118. unsigned long _PgmSize;        /* total size of program area */
  119.  
  120. #ifdef __TURBOC__
  121. char *_StkLim;    /* for Turbo / Pure C stack checking */
  122. extern _StkSize; /* set by linker */
  123. #endif
  124.  
  125. /* default sizeof stdio buffers */
  126. size_t __DEFAULT_BUFSIZ__;    /* .comm             */
  127.  
  128. /* are we an app? */
  129. short _app;
  130.  
  131. /* are we on a split addr mem ST */
  132. short _split_mem = 0;
  133.  
  134. static long parseargs    __PROTO((BASEPAGE *));
  135.  
  136. /*
  137.  * accessories start here:
  138.  */
  139.  
  140. static char    *acc_argv[] = {"", (char *) 0}; /* no name and no arguments */
  141.  
  142. void _acc_main()
  143. {
  144. #ifdef __TURBOC__
  145.     if (&_StkSize == 0)
  146.     {
  147. #endif
  148.  
  149.     if (_stksize == 0 || _stksize == -1L)
  150.         _stksize = MINKEEP;
  151.  
  152.     if (_stksize < 0)
  153.         _stksize = -_stksize;
  154.     _stksize &= 0xfffffffeL;    /* stack on word boundary */
  155.  
  156. #ifdef __TURBOC__
  157.     }
  158.     else
  159.     {
  160.         /* This compound statement is executed if the Pure linker
  161.         has reserved space for the stack in the BSS */
  162.         _stksize = (long) &_StkSize;
  163.         _heapbase = _base->p_bbase + _base->p_blen - _stksize;
  164.     }
  165.     _StkLim = (char *) _heapbase + 256;     /* for stack checking */
  166. #endif
  167.   
  168.     if (_heapbase == 0) {
  169.         _heapbase = (void *)Malloc(_stksize);
  170.     }
  171.     _setstack((char *) _heapbase + _stksize);
  172.     _app = 0;                /* this is an accessory */
  173.  
  174.     _main(1L, acc_argv, acc_argv);
  175.     /*NOTREACHED*/
  176. }
  177.  
  178. void _crtinit()
  179. {
  180.     register BASEPAGE *bp;
  181.     register long m;
  182.     register long freemem;
  183. #ifdef __GNUC__
  184.     extern void etext();    /* a "function" to fake out pc-rel addressing */
  185. #endif
  186.     _app = 1;    /* its an application */
  187.     if(!__DEFAULT_BUFSIZ__)
  188.         __DEFAULT_BUFSIZ__ = BUFSIZ;
  189.  
  190.     bp = _base;
  191.  
  192.     m = parseargs(bp);    /* m = # bytes used by environment + args */
  193.  
  194. /* make m the total number of bytes required by program sans stack/heap */
  195.     m += (bp->p_tlen + bp->p_dlen + bp->p_blen + sizeof(BASEPAGE));
  196.     m = (m + 3L) & (~3L);
  197.  
  198. #ifdef __TURBOC__
  199.     if (&_StkSize == 0)
  200.     {
  201. #endif
  202.  
  203. /* freemem the amount of free mem accounting for MINFREE at top */
  204.     if((freemem = (long)bp->p_hitpa - (long)bp - MINFREE - m) <= 0L)
  205.         goto notenough;
  206.     
  207.     if(_initial_stack)
  208.     {
  209.         /* the primary use of _initial_stack will be in dumping */
  210.         /* applications where only a heap for malloc makes sense */
  211.         _heapbase = (void *) ((long)bp + m);
  212.         _stksize = _initial_stack;
  213.     } else {
  214.         if (_stksize >= -1L)
  215.         _split_mem = 1; /* malloc from Malloc first, then from own heap */
  216.     }
  217.  
  218.     if (_stksize == -1L) {
  219.         _stksize = freemem;
  220.         _heapbase = (void *) ((long)bp + m);
  221.     } else if (_stksize == 0L) {    /* free all but MINKEEP */
  222.         _stksize = MINKEEP;
  223.     } else if (_stksize == 1L) {     /* keep 1/4, free 3/4 */
  224.         _stksize = freemem >> 2;
  225.     } else if (_stksize ==  2L) {    /* keep 1/2, free 1/2 */
  226.         _stksize = freemem >> 1;
  227.     } else if (_stksize == 3L) {    /* keep 3/4, free 1/4 */
  228.         _stksize = freemem - (freemem >> 2); 
  229.     } else {
  230.         if(_stksize < -1L) { /* keep |_stksize|, use heap for mallocs */
  231.         _stksize = -_stksize;
  232.         _heapbase = (void *)((long)bp + m);
  233.         }
  234.     }
  235.     
  236. /* make m the total number of bytes including stack */
  237.     _stksize = _stksize & (~3L);
  238.     m += _stksize;
  239.  
  240. /* make sure there's enough room for the stack */
  241.     if (((long)bp + m) > ((long)bp->p_hitpa - MINFREE))
  242.         goto notenough;
  243.  
  244. /* set up the new stack to bp + m  */
  245.  
  246. #ifdef __TURBOC__
  247.     {
  248.         char *tmp;
  249.         tmp = (char *) bp + m;
  250.         _setstack(tmp);
  251.         _StkLim = tmp - _stksize + 256; /* for stack checking */
  252.     }
  253. #else
  254.     _setstack((char *)bp + m);
  255. #endif
  256.  
  257. #ifdef __TURBOC__
  258.     } /* if (&_StkSize == 0) */
  259.     else
  260.     {
  261.         /* This compound statement is executed if the Pure linker
  262.         has reserved space for the stack in the BSS */
  263.         _stksize = (long) &_StkSize;
  264.         _stksize = _stksize & (~3L);
  265.         
  266.         {
  267.             char *tmp;
  268.             tmp = (char *) bp->p_bbase + bp->p_blen;
  269.             _setstack(tmp);
  270.             _StkLim = tmp - _stksize + 256; /* for stack checking */
  271.             _heapbase = NULL; /* no mallocs from heap */
  272.         }
  273.     }
  274. #endif /* __TURBOC__ */
  275.  
  276. /* shrink the TPA */
  277.     (void)Mshrink(bp, m);
  278.  
  279. /* keep length of program area */
  280.     _PgmSize = m;
  281.  
  282. /* establish handlers,  call the main routine */
  283.     _init_signal();
  284.  
  285. /* start profiling, if we were linked with gcrt0.o */
  286. #ifdef __GNUC__
  287.     _monstart